package com.hoolai.qps.netty.proto;

import java.net.InetSocketAddress;
import java.util.Scanner;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

import com.google.protobuf.GeneratedMessage;
import com.hoolai.qps.bo.ReqCmdProtoFactory;
import com.hoolai.qps.codes.netty.LengthFieldBasedFrameDecoder;
import com.hoolai.qps.codes.netty.client.ClientChannelHandler;
import com.hoolai.qps.codes.netty.client.ClientDecoder;
import com.hoolai.qps.codes.netty.client.ClientEncoder;

public class Client {

    public static void main(String[] args) {
        new Client(new InetSocketAddress("127.0.0.1", 2222));
    }

    public Client() {
    }

    public Client(InetSocketAddress address) {
        ClientBootstrap bootstrap = getBootstrap(address);
        ChannelFuture future = bootstrap.connect();// connect proxy server
        Channel channel = future.awaitUninterruptibly().getChannel();
        new MessageProcess().sendMessage(channel);
        future.getChannel().getCloseFuture().awaitUninterruptibly();
        bootstrap.releaseExternalResources();
    }

    protected ClientBootstrap getBootstrap(InetSocketAddress address) {
        ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors
                .newCachedThreadPool(), Executors.newCachedThreadPool()));
        bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            public ChannelPipeline getPipeline() throws Exception {
                return Channels.pipeline(new LengthFieldBasedFrameDecoder(81920, 0, 4, 0, 4, true),
                        new ClientEncoder(), new ClientDecoder(), new ClientChannelHandler());
            }
        });
        bootstrap.setOption("remoteAddress", address);
        return bootstrap;
    }

    public class MessageProcess {
        public void sendMessage(Channel channel) {
            Scanner sc = new Scanner(System.in);
            ReqCmdProtoFactory potoFactory = new ReqCmdProtoFactory();
            while (true) {
                System.out.println("cmd id:");
                int cmdId = sc.nextInt();
                if (cmdId == 0) {
                    break;
                }
                GeneratedMessage message = potoFactory.getReqCmdProtoByCmdId(cmdId);
                channel.write(new Cmd(message, cmdId));
            }
            channel.close();
        }
    }

    public static class Cmd {
        private GeneratedMessage message;

        private int cmdId;

        public GeneratedMessage getMessage() {
            return message;
        }

        public void setMessage(GeneratedMessage message) {
            this.message = message;
        }

        public int getCmdId() {
            return cmdId;
        }

        public void setCmdId(int cmd) {
            this.cmdId = cmd;
        }

        public Cmd(GeneratedMessage message, int cmd) {
            super();
            this.message = message;
            this.cmdId = cmd;
        }
    }

}
